<template>
  <view class="tn-custom-nav-bar-class tn-custom-nav-bar" :style="[navBarStyle]">
    <view class="tn-custom-nav-bar__bar" :class="[barClass]" :style="[barStyle]">
      <view v-if="isBack">
        <view v-if="customBack">
          <view :style="{
            width: customBackStyleInfo.width + 'px',
            height: customBackStyleInfo.height + 'px',
            marginLeft: customBackStyleInfo.left + 'px'
          }">
            <slot name="back"></slot>
          </view>
        </view>
        <view v-else class="tn-custom-nav-bar__bar__action" @tap="handlerBack">
          <text class="tn-custom-nav-bar__bar__action--nav-back" :class="[`tn-icon-${backIcon}`]"></text>
          <text class="tn-custom-nav-bar__bar__action--nav-back-text" v-if="backTitle">{{ backTitle }}</text>
        </view>
      </view>
      <view class="tn-custom-nav-bar__bar__content" :style="[contentStyle]">
        <slot></slot>
      </view>
      <view>
        <slot name="right"></slot>
      </view>
    </view>
  </view>
</template>

<script>
import componentsColorMixin from '../../libs/mixin/components_color.js'
export default {
  name: 'tn-nav-bar',
  mixins: [componentsColorMixin],
  props: {
    // 层级
    zIndex: {
      type: Number,
      default: 0
    },
    // 导航栏的高度
    height: {
      type: Number,
      default: 0
    },
    // 高度单位
    unit: {
      type: String,
      default: 'px'
    },
    // 是否显示返回按钮
    isBack: {
      type: Boolean,
      default: true
    },
    // 返回按钮的图标
    backIcon: {
      type: String,
      default: 'left'
    },
    // 返回按钮旁显示的文字
    backTitle: {
      type: String,
      default: '返回'
    },
    // 透明状态栏
    alpha: {
      type: Boolean,
      default: false
    },
    // 是否固定在顶部
    fixed: {
      type: Boolean,
      default: true
    },
    // 是否显示底部阴影
    bottomShadow: {
      type: Boolean,
      default: true
    },
    // 是否自定义返回按钮
    customBack: {
      type: Boolean,
      default: false
    },
    // 返回前回调
    beforeBack: {
      type: Function,
      default: null
    },
    index: {
      type: Boolean,
      default: false
    },
  },
  computed: {
    navBarStyle() {
      let style = {}
      style.height = this.height === 0 ? this.customBarHeight + this.unit : this.height + this.unit
      if (this.fixed && !this.index) {
        style.position = 'fixed'
      }
      style.zIndex = this.elZIndex
      return style
    },
    barClass() {
      let clazz = ''
      if (this.backgroundColorClass) {
        clazz += ` ${this.backgroundColorClass}`
      }
      if (this.fontColorClass) {
        clazz += `${this.fontColorClass}`
      }
      if (this.fixed) {
        clazz += ' tn-custom-nav-bar__bar--fixed'
      }
      if (this.alpha) {
        clazz += ' tn-custom-nav-bar__bar--alpha'
      }
      if (this.bottomShadow) {
        clazz += ' tn-custom-nav-bar__bar--bottom-shadow'
      }
      return clazz
    },
    barStyle() {
      let style = {}
      style.height = this.height === 0 ? this.customBarHeight + this.unit : this.height + this.unit

      if (this.fixed) {
        style.paddingTop = this.statusBarHeight + 'px'
      }

      if (!this.backgroundColorClass) {
        style.backgroundColor = this.backgroundColor !== '' ? this.backgroundColor : '#FFFFFF'
        // style['background-image'] = 'linear-gradient(to right, #dfebfe, #fbfbfb, #ccfcfa); !important'
      }
      if (!this.fontColorClass && this.fontColor) {
        style.color = this.fontColor
      }
      style.zIndex = this.elZIndex
      return style
    },
    contentStyle() {
      let style = {}
      style.top = this.fixed ? this.statusBarHeight + 'px' : '0px'
      style.height = this.height === 0 ? (this.customBarHeight - this.statusBarHeight) + this.unit : this.height + this.unit
      style.lineHeight = style.height

      if (this.isBack) {
        if (this.customBack) {
          const width = (this.customBackStyleInfo.width + this.customBackStyleInfo.left) * 2
          style.width = `calc(100% - ${width}px)`
        } else {
          style.width = 'calc(100% - 340rpx)'
        }
      } else {
        style.width = '100%'
      }

      return style
    },
    elZIndex() {
      return this.zIndex ? this.zIndex : this.$t.zIndex.navbar
    }
  },
  data() {
    return {
      // 状态栏的高度
      statusBarHeight: 0,
      // 自定义导航栏的高度
      customBarHeight: 0,
      // 自定义返回按钮时，返回容器的宽高边距信息
      customBackStyleInfo: {
        width: 86,
        height: 32,
        left: 15
      }
    }
  },
  mounted() {
    // 获取vuex中的自定义顶栏的高度
    this.updateNavBarInfo()
  },
  created() {
    // 获取胶囊信息
    // #ifdef MP-WEIXIN
    let custom = wx.getMenuButtonBoundingClientRect()
    this.customBackStyleInfo.width = custom.width
    this.customBackStyleInfo.height = custom.height
    this.customBackStyleInfo.left = uni.upx2px(750) - custom.right
    // #endif
  },
  methods: {
    // 更新导航栏的高度
    async updateNavBarInfo() {
      // 获取vuex中的自定义顶栏的高度
      let customBarHeight = this.vuex_custom_bar_height
      let statusBarHeight = this.vuex_status_bar_height
      // 如果获取失败则重新获取
      if (!customBarHeight) {
        try {
          const navBarInfo = await this.$t.updateCustomBar()
          customBarHeight = navBarInfo.customBarHeight
          statusBarHeight = navBarInfo.statusBarHeight
        } catch (e) {
          setTimeout(() => {
            this.updateNavBarInfo()
          }, 10)
          return
        }
      }

      // 更新vuex中的导航栏信息
      this && this.$t.vuex('vuex_status_bar_height', statusBarHeight)
      this && this.$t.vuex('vuex_custom_bar_height', customBarHeight)

      this.customBarHeight = customBarHeight
      this.statusBarHeight = statusBarHeight
    },
    // 处理返回事件
    async handlerBack() {
      if (this.beforeBack && typeof (this.beforeBack) === 'function') {
        // 执行回调，同时传入索引当作参数
        // 在微信，支付宝等环境(H5正常)，会导致父组件定义的函数体中的this变成子组件的this
        // 通过bind()方法，绑定父组件的this，让this的this为父组件的上下文
        let beforeBack = this.beforeBack.bind(this.$t.$parent.call(this))()
        // 判断是否返回了Promise
        if (!!beforeBack && typeof beforeBack.then === 'function') {
          await beforeBack.then(res => {
            // Promise返回成功
            this.navBack()
          }).catch(err => { })
        } else if (beforeBack === true) {
          this.navBack()
        }
      } else {
        this.navBack()
      }
    },
    // 返回上一页
    navBack() {

      // 通过判断当前页面的页面栈信息，是否有上一页进行返回，如果没有则跳转到首页
      const pages = getCurrentPages()
      if (pages && pages.length > 0) {
        const firstPage = pages[0]
        if (pages.length == 1 && (!firstPage.route || firstPage.route != 'pages/index/index')) {
          uni.reLaunch({
            url: '/pages/index/index'
          })
        } else {
          uni.navigateBack({
            delta: 1
          })
        }
      } else {
        uni.reLaunch({
          url: '/pages/index/index'
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.tn-custom-nav-bar {
  display: block;
  position: relative;

  &__bar {
    display: flex;
    position: relative;
    align-items: center;
    min-height: 100rpx;
    justify-content: space-between;
    min-height: 0px;
    /* #ifdef MP-WEIXIN */
    padding-right: 220rpx;
    /* #endif */
    /* #ifdef MP-ALIPAY */
    padding-right: 150rpx;
    /* #endif */
    box-shadow: 0rpx 0rpx 0rpx;
    z-index: 9999;

    &--fixed {
      position: fixed;
      width: 100%;
      top: 0;
    }

    &--alpha {
      background: transparent !important;
      box-shadow: none !important;
    }

    &--bottom-shadow {
      box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.1);
    }

    &__action {
      display: flex;
      align-items: center;
      height: 100%;
      justify-content: center;
      max-width: 100%;

      &--nav-back {
        /* position: absolute; */
        /* top: 50%; */
        /* left: 20rpx; */
        /* margin-top: -15rpx; */
        // width: 25rpx;
        // height: 25rpx;
        padding: 20rpx;
        font-size: 38rpx;
        line-height: 100%;
        // border-width: 0 0 4rpx 4rpx;
        // border-color: #000000;
        // border-style: solid;
        // transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
      }

      &--nav-back-text {
        padding: 20rpx 20rpx 20rpx 0rpx;
      }
    }

    &__content {
      position: absolute;
      text-align: center;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
      font-size: 32rpx;
      cursor: none;
      // pointer-events: none;
      text-overflow: ellipsis;
      white-space: nowrap;
      overflow: hidden;
    }
  }
}
</style>
